package com.practice.zuocy.base.class02;

/**
 * 环状数组实现队列
 */
public class Code04_RingArray {

	// 数组(固定长度的数组)实现队列（环状=结构）
	public static class MyQueue {
		private int[] arr;
		// 新进的数打算放哪里
		private int pushi;
		// 如果用户需要数据，从哪个位置去拿数据
		private int polli;
		// 队列的size
		private int size;
		// 数组长度限制
		private final int limit;

		/**
		 * 构造函数
		 *
		 * @param limit 数组长度限制
		 */
		public MyQueue(int limit) {
			// 初始化数组，长度为传入的limit
			arr = new int[limit];
			// 开始时pushi == 0
			pushi = 0;
			// 开始时polli == 0
			polli = 0;
			// 开始时，队列里面一个元素也还没有放，size为0
			size = 0;
			this.limit = limit;
		}

		/**
		 * 往队列中放入一个数
		 *
		 * @param value 待放入的数
		 */
		public void push(int value) {
			if (size == limit) {
				// 队列已经满了
				throw new RuntimeException("栈满了，不能再加了");
			}
			size++;
			// pushi位置直接放入value
			arr[pushi] = value;
			// 更新pushi的位置
			pushi = nextIndex(pushi);
		}

		/**
		 * 从队列中弹出一个数
		 *
		 * @return 弹出的数
		 */
		public int pop() {
			if (size == 0) {
				// 队列为空
				throw new RuntimeException("栈空了，不能再拿了");
			}
			size--;
			// 取出polli位置的值
			int ans = arr[polli];
			// 更新polli的位置
			polli = nextIndex(polli);
			return ans;
		}

		/**
		 * 判断队列是否为空
		 *
		 * @return
		 */
		public boolean isEmpty() {
			return size == 0;
		}

		// 如果现在的下标是i，返回下一个位置
		private int nextIndex(int i) {
			return i < limit - 1 ? i + 1 : 0;
		}

	}

}
